package com.carleasoft.mps.core.utils;

import com.carleasoft.mps.core.exceptions.BaseException;
import com.carleasoft.mps.core.exceptions.BaseRunTimeException;
import com.carleasoft.mps.core.result.BaseResult;
import lombok.SneakyThrows;

import java.lang.reflect.Constructor;

/**
 * 异常工具类w
 *
 * @author Alay
 * @date 2021-07-07 13:52
 * @project jmrh
 */
public class ExceptionUtil {


    /**
     * 创建通用异常
     * @param baseResult
     * @return
     */
    public static BaseRunTimeException create(BaseResult baseResult) {
        BaseRunTimeException exception = new BaseRunTimeException(baseResult);
        return exception;
    }

    /**
     * 创建一个异常对象实例,此函数没有做过多的逻辑处理,要求必须具备空餐构造器且public修饰
     *
     * @param eClazz
     * @param <E>
     * @return
     */
    @SneakyThrows
    public static <E extends BaseRunTimeException> E create(Class<E> eClazz) {
        Constructor<E> constructor = eClazz.getConstructor();
        E exceptionInstance = constructor.newInstance();
        return exceptionInstance;
    }

    /**
     * 创建一个异常对象实例,要求必须具备空餐构造器
     *
     * @param eClazz
     * @param code
     * @param msg
     * @param <E>
     * @return
     */
    @SneakyThrows
    public static <E extends BaseRunTimeException> E create(Class<E> eClazz, String code, String msg) {
        E exceptionInstance = ExceptionUtil.create(eClazz);
        exceptionInstance.setCode(code);
        exceptionInstance.setMsg(msg);
        return exceptionInstance;
    }

    /**
     * 创建一个异常对象实例,要求必须具备空餐构造器
     *
     * @param eClazz
     * @param baseResult
     * @param <E>
     * @return
     */
    @SneakyThrows
    public static <E extends BaseRunTimeException> E create(Class<E> eClazz, BaseResult baseResult) {
        E exceptionInstance = ExceptionUtil.create(eClazz);
        exceptionInstance.setCode(baseResult.getCode());
        exceptionInstance.setMsg(baseResult.getMessage());
        return exceptionInstance;
    }


    /**
     * 往外抛出的异常
     * 创建一个异常对象实例,此函数没有做过多的逻辑处理,要求必须具备空餐构造器且public修饰
     *
     * @param eClazz
     * @param baseResult
     * @param <E>
     * @return
     */
    @SneakyThrows
    public static <E extends BaseException> E doThrow(Class<E> eClazz, BaseResult baseResult) {
        Constructor<E> constructor = eClazz.getConstructor();
        constructor.setAccessible(true);
        E exceptionInstance = constructor.newInstance();
        exceptionInstance.setCode(baseResult.getCode());
        exceptionInstance.setMsg(baseResult.getMessage());
        return exceptionInstance;
    }
}
